From: Keir Fraser Date: Fri, 28 May 2010 07:14:54 +0000 (+0100) Subject: HAP: Add hardware capability check for 2MB super page. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~12069 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=6a47fbab768d968172e19966312b30e3d1269e73;p=xen.git HAP: Add hardware capability check for 2MB super page. While setting the HAP entry previously, we only check the hardware capability for 1GB super page. This patch adds hardware capability check for 2MB superpage Also, Intel SDM doesn't exclude 1GB feature for 32/pae host. Therefore remove the BUG_ON() check in common code. Signed-off-by: Dongxiao Xu --- diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 0bc9f11781..d897b43c7d 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -935,8 +935,9 @@ struct hvm_function_table * __init start_svm(void) cpuid_edx(0x8000000A) : 0); svm_function_table.hap_supported = cpu_has_svm_npt; - svm_function_table.hap_1gb_pgtb = - (CONFIG_PAGING_LEVELS == 4)? !!(cpuid_edx(0x80000001) & 0x04000000):0; + svm_function_table.hap_superpage_level = + ((CONFIG_PAGING_LEVELS == 4) && (cpuid_edx(0x80000001) & 0x04000000)) ? + 2 : 1; return &svm_function_table; } diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index e74032a9d2..39f5cb51ea 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -94,7 +94,8 @@ static void __init vmx_display_features(void) if ( vmx_ept_super_page_level_limit ) printk("EPT supports %s super page.\n", - vmx_ept_super_page_level_limit > 1 ? "1G" : "2M"); + (vmx_ept_super_page_level_limit == 2) ? "1G" : + ((vmx_ept_super_page_level_limit == 1) ? "2M" : "4K")); } static u32 adjust_vmx_controls( diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index d60a552ca2..3432e927d5 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1435,7 +1435,7 @@ struct hvm_function_table * __init start_vmx(void) setup_ept_dump(); } - vmx_function_table.hap_1gb_pgtb = (vmx_ept_super_page_level_limit == 2); + vmx_function_table.hap_superpage_level = vmx_ept_super_page_level_limit; setup_vmcs_dump(); diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 5dd4a16e47..46c53c13ea 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1757,17 +1757,13 @@ int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, { if ( is_hvm_domain(d) && paging_mode_hap(d) ) order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) && - hvm_funcs.hap_1gb_pgtb && opt_hap_1gb ) ? 18 : - (((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) ? 9 : 0; + (hvm_funcs.hap_superpage_level == 2) && + opt_hap_1gb ) ? 18 : + ((((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) && + (hvm_funcs.hap_superpage_level >= 1)) ? 9 : 0; else order = 0; - /* Note that we only enable hap_1gb_pgtb when CONFIG_PAGING_LEVELS==4. - * So 1GB should never be enabled under 32bit or PAE modes. But for - * safety's reason, we double-check the page order again.. - */ - BUG_ON(order == 18 && CONFIG_PAGING_LEVELS < 4); - if ( !d->arch.p2m->set_entry(d, gfn, mfn, order, p2mt) ) rc = 0; gfn += 1ul << order; diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index a2845d6c93..40719bb2cf 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -72,8 +72,11 @@ struct hvm_function_table { /* Support Hardware-Assisted Paging? */ int hap_supported; - /* Support 1GB Harware-Assisted Paging? */ - int hap_1gb_pgtb; + /* + * Indicate HAP super page level. + * 0 -- 4KB, 1 -- 2MB, 2 -- 1GB. + */ + int hap_superpage_level; /*